﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;

namespace RazorBridge.Mvc
{
    public class FrameworkConfiguration : ConfigurationSection
    {
        [ConfigurationProperty("Devices")]
        [ConfigurationCollection(typeof(DeviceConfigCollection), AddItemName = "Device")]
        public DeviceConfigCollection DeviceConfigs
        {
            get { return (DeviceConfigCollection)base["Devices"]; }

        }

        [ConfigurationProperty("PluginConfigs")]
        [ConfigurationCollection(typeof(PluginConfigCollection), AddItemName = "PluginConfig")]
        public PluginConfigCollection PluginConfigs
        {
            get { return (PluginConfigCollection)base["PluginConfigs"]; }
        }
       
    }

    #region "Device Support"

    public class DeviceConfigCollection : ConfigurationElementCollection, IEnumerable<DeviceConfigElement>
    {
        [ConfigurationProperty("DefaultDevice", DefaultValue= Device.Desktop)]
        public Device DefaultDevice
        {
            get
            {
                return (Device)this["DefaultDevice"];
            }
            set
            {
                this["DefaultDevice"] = value;
            }
        }
        protected override ConfigurationElement CreateNewElement()
        {
            return new DeviceConfigElement();
        }

        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((DeviceConfigElement)element).DeviceType;
        }

        public DeviceConfigElement this[int index]
        {
            get { return (DeviceConfigElement)BaseGet(index); }
        }

        public DeviceConfigElement this[Device key]
        {
            get { return (DeviceConfigElement)BaseGet(key); }
        }

        #region IEnumerable<DeviceConfigElement> Members

        public new IEnumerator<DeviceConfigElement> GetEnumerator()
        {
            return (IEnumerator<DeviceConfigElement>)GetEnumerator();
        }

        #endregion
    }

    public class DeviceConfigElement : ConfigurationElement
    {
        [ConfigurationProperty("DeviceType", IsKey = true, IsRequired = true)]
        public Device DeviceType
        {
            get
            {
                return (Device)this["DeviceType"];
            }
            set
            {
                this["DeviceType"] = value;
            }
        }

        [ConfigurationProperty("UserAgent", IsRequired = true)]
        public string UserAgent
        {
            get
            {
                return (string)this["UserAgent"];
            }
            set
            {
                this["UserAgent"] = value;
            }
        }

        [ConfigurationProperty("Platforms")]
        [ConfigurationCollection(typeof(Platformollection), AddItemName = "Platform")]
        public Platformollection Platforms
        {
            get { return (Platformollection)base["Platforms"]; }
        }

    }

    #endregion

    #region "Platform Support"

    public class Platformollection : ConfigurationElementCollection, IEnumerable<PlatformElement>
    {
        protected override ConfigurationElement CreateNewElement()
        {
            return new PlatformElement();
        }

        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((PlatformElement)element).PlatformType;
        }

        public PlatformElement this[int index]
        {
            get { return (PlatformElement)BaseGet(index); }
        }

        public PlatformElement this[Platform key]
        {
            get { return (PlatformElement)BaseGet(key); }
        }

        #region IEnumerable<PlatformElement> Members

        public new IEnumerator<PlatformElement> GetEnumerator()
        {
            return (IEnumerator<PlatformElement>)GetEnumerator();
        }

        #endregion
    }

    public class PlatformElement : ConfigurationElement
    {
        [ConfigurationProperty("PlatformType", IsKey = true, IsRequired = true)]
        public Platform PlatformType
        {
            get
            {
                return (Platform)this["PlatformType"];
            }
            set
            {
                this["PlatformType"] = value;
            }
        }

        [ConfigurationProperty("UserAgent", IsRequired = true)]
        public string UserAgent
        {
            get
            {
                return (string)this["UserAgent"];
            }
            set
            {
                this["UserAgent"] = value;
            }
        }

    }

    #endregion

    #region  "Plugin Configuration"

    public class PluginConfigCollection : ConfigurationElementCollection, IEnumerable<PluginElement>
    {
        protected override ConfigurationElement CreateNewElement()
        {
            return new PluginElement();
        }

        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((PluginElement)element).Key;
        }

        public PluginElement this[int index]
        {
            get { return (PluginElement)BaseGet(index); }
        }

        new public PluginElement this[string key]
        {
            get { return (PluginElement)BaseGet(key); }
        }

        #region IEnumerable<PluginElement> Members

        public new IEnumerator<PluginElement> GetEnumerator()
        {
            return (IEnumerator<PluginElement>)GetEnumerator();
        }

        #endregion
    }

    public class PluginElement : ConfigurationElement
    {
        [ConfigurationProperty("Key", IsKey = true, IsRequired = true)]
        public string Key
        {
            get
            {
                return (string)this["Key"];
            }
            set
            {
                this["Key"] = value;
            }
        }

        [ConfigurationProperty("IsEmbeddedResource", DefaultValue=(bool)true)]
        public bool IsEmbeddedResource
        {
            get
            {
                return (bool)this["IsEmbeddedResource"];
            }
            set
            {
                this["IsEmbeddedResource"] = value;
            }
        }

        [ConfigurationProperty("Assembly", IsRequired = false)]
        public string Assembly
        {
            get
            {
                return (string)this["Assembly"];
            }
            set
            {
                this["Assembly"] = value;
            }
        }

        [ConfigurationProperty("ViewConfigs")]
        [ConfigurationCollection(typeof(ViewConfigCollection), AddItemName = "ViewConfig")]
        public ViewConfigCollection ViewConfigs
        {
            get { return (ViewConfigCollection)base["ViewConfigs"]; }
        }

    }

    #endregion

    #region "View Configurations"
    public class ViewConfigCollection : ConfigurationElementCollection, IEnumerable<ViewConfigElement>
    {
        protected override ConfigurationElement CreateNewElement()
        {
            return new ViewConfigElement();
        }

        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((ViewConfigElement)element).DeviceType;
        }

        public ViewConfigElement this[int index]
        {
            get { return (ViewConfigElement)BaseGet(index); }
        }

        public ViewConfigElement this[Device key]
        {
            get { return (ViewConfigElement)BaseGet(key); }
        }

        #region IEnumerable<ViewConfigElement> Members

        public new IEnumerator<ViewConfigElement> GetEnumerator()
        {
            return (IEnumerator<ViewConfigElement>)GetEnumerator();
        }

        #endregion
    }

    public class ViewConfigElement : ConfigurationElement
    {
        [ConfigurationProperty("DeviceType", IsKey = true, IsRequired = true)]
        public Device DeviceType
        {
            get
            {
                return (Device)this["DeviceType"];
            }
            set
            {
                this["DeviceType"] = value;
            }
        }


        [ConfigurationProperty("Views")]
        [ConfigurationCollection(typeof(ViewCollection), AddItemName = "View")]
        public ViewCollection Views
        {
            get { return (ViewCollection)base["Views"]; }
        }


        [ConfigurationProperty("PartialViews")]
        [ConfigurationCollection(typeof(ViewCollection), AddItemName = "PartialView")]
        public ViewCollection PartialViews
        {
            get { return (ViewCollection)base["PartialViews"]; }
        }

        [ConfigurationProperty("PlatformViews", IsRequired=false)]
        [ConfigurationCollection(typeof(PlatformViewConfigCollection), AddItemName = "PlatformView")]
        public PlatformViewConfigCollection PlatformViews
        {
            get { return (PlatformViewConfigCollection)base["PlatformViews"]; }
        }

    }

    #region "Platform Views"

    public class PlatformViewConfigCollection : ConfigurationElementCollection, IEnumerable<PlatformViewElement>
    {
        protected override ConfigurationElement CreateNewElement()
        {
            return new PlatformViewElement();
        }

        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((PlatformViewElement)element).PlatformType;
        }

        public PlatformViewElement this[int index]
        {
            get { return (PlatformViewElement)BaseGet(index); }
        }

        public PlatformViewElement this[Platform key]
        {
            get { return (PlatformViewElement)BaseGet(key); }
        }

        #region IEnumerable<PlatformViewElement> Members

        public new IEnumerator<PlatformViewElement> GetEnumerator()
        {
            return (IEnumerator<PlatformViewElement>)GetEnumerator();
        }

        #endregion
    }

    public class PlatformViewElement : ConfigurationElement
    {
        [ConfigurationProperty("PlatformType", IsKey = true, IsRequired = true)]
        public Platform PlatformType
        {
            get
            {
                return (Platform)this["PlatformType"];
            }
            set
            {
                this["PlatformType"] = value;
            }
        }

        [ConfigurationProperty("Views")]
        [ConfigurationCollection(typeof(ViewCollection), AddItemName = "View")]
        public ViewCollection Views
        {
            get { return (ViewCollection)base["Views"]; }
        }

        [ConfigurationProperty("PartialViews")]
        [ConfigurationCollection(typeof(ViewCollection), AddItemName = "PartialView")]
        public ViewCollection PartialViews
        {
            get { return (ViewCollection)base["PartialViews"]; }
        }
        
    }

    #endregion

    public class ViewCollection : ConfigurationElementCollection, IEnumerable<ViewElement>
    {
        protected override ConfigurationElement CreateNewElement()
        {
            return new ViewElement();
        }

        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((ViewElement)element).Key;
        }

        public ViewElement this[int index]
        {
            get { return (ViewElement)BaseGet(index); }
        }

        new public ViewElement this[string key]
        {
            get { return (ViewElement)BaseGet(key); }
        }

        #region IEnumerable<ViewElement> Members

        public new IEnumerator<ViewElement> GetEnumerator()
        {
            return (IEnumerator<ViewElement>)GetEnumerator();
        }

        #endregion
    }

    public class ViewElement : ConfigurationElement
    {
        [ConfigurationProperty("Key", IsKey = true, IsRequired = true)]
        public string Key
        {
            get
            {
                return (string)this["Key"];
            }
            set
            {
                this["Key"] = value;
            }
        }

        [ConfigurationProperty("Path", IsRequired = true)]
        public string Path
        {
            get
            {
                return (string)this["Path"];
            }
            set
            {
                this["Path"] = value;
            }
        }

        [ConfigurationProperty("Assembly", IsRequired = false)]
        public string Assembly
        {
            get
            {
                return (string)this["Assembly"];
            }
            set
            {
                this["Assembly"] = value;
            }
        }

    }
    #endregion
}
